package com.paic.common.util;

import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;

/**
 * @author Jerry
 */
public class StringUtil {

	public static final String FILE_SEPARATOR = System.getProperty("file.separator");

	/**
	 * the true if this content is null or does not have the any character
	 */
	public static boolean isEmpty(Object value) {
		if (value == null || value.equals("null")) {
			return true;
		}

		if (value instanceof String) {
			if (((String) value).length() == 0) {
				return true;
			}

			return false;
		} else if (value.getClass().isArray()) {
			if (Array.getLength(value) == 0) {
				return true;
			}
		}

		return false;
	}

	/**
	 * To lower character at index, the first element index is zero.
	 * 
	 * @param content
	 * @param index
	 * @return
	 */
	public static String toLowerCaseAtIndex(String content, int index) {
		if (isEmpty(content)) {
			throw new IllegalArgumentException("Argument cannot be null or empty.");
		}

		if (index < 0 || index >= content.length()) {
			throw new IllegalArgumentException("Index range should at [0, content.length())");
		}

		return content.substring(0, index) + String.valueOf(Character.toLowerCase(content.charAt(index)))
				+ content.substring(index + 1);
	}

	public static String toUpperCaseAtIndex(String content, int index) {
		if (isEmpty(content)) {
			throw new IllegalArgumentException("Argument cannot be null or empty.");
		}

		if (index < 0 || index >= content.length()) {
			throw new IllegalArgumentException("Index range should at [0, content.length())");
		}

		return content.substring(0, index) + String.valueOf(Character.toUpperCase(content.charAt(index)))
				+ content.substring(index + 1);
	}

	public static String templateReplace(String template, String split, String[] args) {
		if (isEmpty(template) || isEmpty(split) || isEmpty(args)) {
			throw new IllegalArgumentException("Arguments should contail contents");
		}

		if (split.equals("|")) {
			split = "\\|";
		}
		String[] templateArray = template.split(split);
		int templateArrayLength = templateArray.length;
		if (template.endsWith(split)) {
			templateArrayLength++;
		}
		if (templateArrayLength - 1 != args.length) {
			throw new IllegalArgumentException("Args cannot match template");
		}

		StringBuffer sb = new StringBuffer();

		for (int i = 0; i < args.length; i++) {
			sb.append(templateArray[i]).append(args[i]);
		}
		if (!template.endsWith(split)) {
			sb.append(templateArray[templateArray.length - 1]);
		}

		return sb.toString();
	}

	public static <T> String toString(T[] arr) {
		String result = "";
		if (!isEmpty(arr)) {
			result = StringUtils.join(arr, ",");
		}

		return result;
	}

	public static String percent(double divisor, double dividend, boolean percent) {
		if (dividend == 0) {
			return "NaN";
		}

		double result = divisor / dividend;
		String temp = new BigDecimal(result * 100).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
		return percent ? temp + "%" : temp;
	}

	public static String[] addPrefix(String[] source, String prefix) {
		if (!isEmpty(source)) {
			String[] result = new String[source.length];
			for (int i = 0; i < source.length; i++) {
				result[i] = prefix + source[i];
			}
			return result;
		}

		return source;
	}

	public static String[] castStringArray(int[] source) {
		String[] result = (String[]) Array.newInstance(String.class, source.length);
		for (int i = 0; i < source.length; i++) {
			result[i] = String.valueOf(source[i]);
		}

		return result;
	}

	public static <T> boolean contains(String source, Collection<? extends T> c) {
		for (T t : c) {
			String compare = t.toString();
			if (t.getClass().isPrimitive()) {
				compare = t + "";
			}
			if (source.contains(compare)) {
				return true;
			}
		}

		return false;
	}

	public static <T> boolean contains(Collection<? extends T> small, Collection<? extends T> big) {
		for (T t : small) {
			if (!contains(t.toString(), big)) {
				return false;
			}
		}

		return true;
	}

	public static List<String> asList(int[] array) {
		List<String> list = new ArrayList<String>(array.length);
		for (int i : array) {
			list.add(String.valueOf(i));
		}

		return list;
	}

	public static int[] addArray(int[] source, int[] extend) {
		int[] result = (int[]) Array.newInstance(int.class, source.length + extend.length);
		for (int i = 0; i < result.length; i++) {
			if (i < source.length) {
				result[i] = source[i];
			} else {
				result[i] = extend[i - source.length];
			}
		}

		return result;
	}

	public static List<String> toList(String source, String split) {
		return Arrays.asList(source.split(split));
	}

	public static Set<String> arrayAsSet(String[] source) {
		return new HashSet<String>(Arrays.asList(source));
	}

	public static String toUppercase(Object obj) {
		return obj.toString().toUpperCase();
	}

	public static String toLowercase(Object obj) {
		return obj.toString().toLowerCase();
	}

	public String deleteStr(String sourceString, String deleteString) {
		int index = sourceString.indexOf(deleteString);
		if (index > 0) {
			sourceString.replaceAll("," + deleteString + "|" + deleteString + ",", "");
		}
		return sourceString;
	}

	/**
	 * some contain and some not contain return 0, all contain return 1, all not
	 * contain return -1
	 * 
	 * @param small
	 * @param big
	 * @return
	 */
	public static <T> int containRange(Collection<? extends T> small, Collection<? extends T> big) {
		boolean leastOneContain = false;
		boolean leastOneNotContain = false;
		for (T t : small) {
			// 如果不包含
			if (!contains(t.toString(), big)) {
				leastOneNotContain = true;
			} else { // 如果包含
				leastOneContain = true;
			}
		}

		// 如果有部分包含，部分不包含，返回0
		if (leastOneContain && leastOneNotContain) {
			return 0;
		} else if (leastOneNotContain) { // 如果全部不包含，返回-1
			return -1;
		} else { // 如果全部包含，返回1
			return 1;
		}
	}

}
